package com.atwisdom.star.core.bsl.basicClass.impl;

import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.actionType.basicClass.ConfigActionType;
import com.atwisdom.star.common.vo.*;
import com.atwisdom.star.core.bsl.basicClass.ConfigBslService;
import com.atwisdom.star.core.dsl.basicClass.ConfigDslService;
import com.atwisdom.star.exception.pojo.BusinessException;
import lombok.AllArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

@Service
@AllArgsConstructor
public class ConfigBslServiceImpl implements ConfigBslService {

    private ConfigDslService configDslService;

    /**************************************************************************************
     * BSL调用方法入口，在一个事务中组合一组方法；responseFactory为调用组合，execMethod为具体执行方法；
     * 方法传参详见ActionData；方法不同，传参多少不同，但是结构相同
     **************************************************************************************/
    /**
     * 服务工厂方法
     * @param actionDataList 参数
     * @return 参数
     * @throws BusinessException 异常
     */
    @Transactional
    public ResultInfo<?> responseFactory(List<ActionData<JSONObject>> actionDataList) throws BusinessException {
        ResultInfo<?> resultInfo = null;
        for (ActionData<JSONObject> actionData : actionDataList) {
            String action = actionData.getAction();
            ConfigActionType actionType = ConfigActionType.valueOf(action);
            String methodName = actionType.getMethodName();
            resultInfo = this.execMethod(methodName, actionData);
        }
        return resultInfo;
    }

    /**
     * 反射执行业务单元方法
     *
     * @param methodName 方法名
     * @param actionData 方法参数
     * @return 返回结果
     * @throws BusinessException 业务异常
     */
    public ResultInfo<?> execMethod(String methodName, ActionData<JSONObject> actionData) throws BusinessException {
        Class<? extends ConfigBslServiceImpl> clz = this.getClass();
        try {
            Method method = clz.getMethod(methodName, ActionData.class);
            ConfigBslServiceImpl service = (ConfigBslServiceImpl) AopContext.currentProxy();
            return (ResultInfo<?>) method.invoke(service, actionData);
        } catch (NoSuchMethodException ex) {
            throw new BusinessException("999999", "没有找到该方法(" + methodName + ")", ex);
        } catch (IllegalAccessException ex) {
            throw new BusinessException("999999", "没有访问该方法权限(" + methodName + ")", ex);
        } catch (InvocationTargetException ex) {
            Throwable targetException = ex.getTargetException();
            if (targetException instanceof BusinessException) {
                BusinessException bex = (BusinessException) targetException;
                throw new BusinessException("999999", bex.getErrorMsg(), ex);
            } else {
                throw new BusinessException("999999", "出错了请重试：(" + methodName + ")---" + ex.getMessage(), ex);
            }
        }
    }


    @Override
    public ResultInfo<?> add(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        JSONObject jsonObject = data.get(0);
        JSONObject addJsonObject = this.configDslService.add(jsonObject);
        return JsonResult.success(addJsonObject);
    }

    @Override
    public ResultInfo<?> batchAdd(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        List<JSONObject> addJsonObject = this.configDslService.batchAdd(data);
        return JsonResult.success(addJsonObject);
    }

    @Override
    public ResultInfo<?> update(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        JSONObject jsonObject = data.get(0);
        JSONObject addJsonObject = this.configDslService.update(jsonObject);
        return JsonResult.success(addJsonObject);
    }

    @Override
    public ResultInfo<?> batchUpdate(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        List<JSONObject> addJsonObject = this.configDslService.batchUpdate(data);
        return JsonResult.success(addJsonObject);
    }

    @Override
    public ResultInfo<?> deleteByIds(ActionData<JSONObject> actionData) {
        this.configDslService.deleteByIds(actionData.getIds());
        return JsonResult.success(StatusCode.SUCCESS);
    }

    @Override
    public ResultInfo<?> query(ActionData<JSONObject> actionData) {
        String condition = actionData.getCondition();
        String orderBy = actionData.getOrderBy();
        List<JSONObject> query = this.configDslService.query(condition, orderBy);
        return JsonResult.success(query);
    }

    @Override
    public ResultInfo<?> queryInfo(ActionData<JSONObject> actionData) {
        String condition = actionData.getCondition();
        String orderBy = actionData.getOrderBy();
        List<JSONObject> query = this.configDslService.queryInfo(condition, orderBy);
        return JsonResult.success(query);
    }

    @Override
    public ResultInfo<?> queryByIds(ActionData<JSONObject> actionData) {
        List<JSONObject> query = this.configDslService.queryByIds(actionData.getIds());
        return JsonResult.success(query);
    }

    @Override
    public ResultInfo<?> queryByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String condition = actionData.getCondition();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.configDslService.queryByPage(pageNumber, pageSize, condition, orderBy);
        return JsonResult.success(pageInfo);
    }

    @Override
    public ResultInfo<?> queryInfoByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String condition = actionData.getCondition();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.configDslService.queryInfoByPage(pageNumber, pageSize, condition, orderBy);
        return JsonResult.success(pageInfo);
    }
}
